package stream

import (
	"encoding/json"
	"errors"
	"github.com/prometheus/prometheus/prompb"
	"gluenet/pkg/apis"
	"gluenet/pkg/gerrors"
	"gluenet/pkg/meta"
	"strings"
)

func info(c *apis.StorageContext, tms *prompb.TimeSeries) {
	var kv = make(map[string]string, len(tms.Labels))
	for _, label := range tms.Labels {
		kv[label.Name] = label.Value
	}

	switch kv["platform"] {
	case "kubernetes":
		switch kv["object"] {
		case "machine":
			switch kv["label"] {
			case "agent_hosts":
				key := strings.Join([]string{kv["platform"], kv["label"], kv["agent_guid"]}, "|")
				//key := strings.Join([]string{kv["platform"], kv["name"], "3490be2c2477b6f4541fa61286fbd996"}, "|")
				//c.Logger.Debugf("info %v", key)
				infosi, ok := c.InfoFlusher.Info.LoadOrStore(key, make(map[string]string))
				infos := infosi.(map[string]string)
				infos[kv["host_name"]] = ""
				if !ok {
					c.InfoFlusher.Func.Store(key, func(k, v interface{}) error {
						guid := strings.Split(k.(string), "|")[2]
						detail, i := make([]string, len(v.(map[string]string))), 0
						for n := range v.(map[string]string) {
							detail[i] = n
							i++
						}
						str := strings.Join(detail, "|")
						if err := c.DataBase.AgentRuntimeHostUpdate(guid, str); err != nil {
							c.Logger.Errorf("update machine runtime host %v", err)
						}
						return nil
					})
				}
			case "agent_containers":
				//c.Logger.Debugf("here")
				key := strings.Join([]string{kv["platform"], kv["label"], kv["agent_guid"]}, "|")
				//key := strings.Join([]string{kv["platform"], kv["name"], "3490be2c2477b6f4541fa61286fbd996"}, "|")
				infosi, ok := c.InfoFlusher.Info.LoadOrStore(key, make(map[string][3]string))
				infos := infosi.(map[string][3]string)
				infos[kv["container"]] = [3]string{kv["application_guid"], kv["pod"], kv["host_name"]}
				if !ok {
					c.InfoFlusher.Func.Store(key, func(k, v interface{}) error {
						guid := strings.Split(k.(string), "|")[2]
						detail, i := make([]string, len(v.(map[string][3]string))), 0
						for p, n := range v.(map[string][3]string) {
							detail[i] = strings.Join([]string{n[0], p, n[1], n[2]}, ",")
							i++
						}
						str := strings.Join(detail, "|")
						if err := c.DataBase.AgentRuntimeContainersUpdate(guid, str); err != nil {
							c.Logger.Errorf("update agent runtime container %v", err)
						}
						return nil
					})
				}
			}
		case "application":
			switch kv["label"] {
			case "instance_containers":
				key := strings.Join([]string{kv["platform"], kv["label"], kv["application_guid"]}, "|")
				//key := strings.Join([]string{kv["platform"], kv["name"], "07f8c5951cef9eb4121771a9a96f73b4"}, "|")
				//c.Logger.Debugf("info %v", key)
				infosi, ok := c.InfoFlusher.Info.LoadOrStore(key, make(map[string][3]string))
				infos := infosi.(map[string][3]string)
				infos[kv["container"]] = [3]string{kv["pod"], kv["host_name"], kv["agent_guid"]}
				if !ok {
					c.InfoFlusher.Func.Store(key, func(k, v interface{}) error {
						guid := strings.Split(k.(string), "|")[2]
						detail, i := make([]string, len(v.(map[string][3]string))), 0
						for p, n := range v.(map[string][3]string) {
							detail[i] = strings.Join([]string{p, n[0], n[1], n[2]}, ",")
							i++
						}
						str := strings.Join(detail, "|")
						if err := c.DataBase.InstanceRuntimeContainerUpdate(guid, str); err != nil {
							var data *meta.Instance
							if err = c.DataBase.InstanceGet(guid, &data); !errors.Is(err, gerrors.DataNotFind) {
								c.Logger.Errorf("update container_info %v", err)
							}
						}
						return nil
					})
				}
			case "container_info":
				key := strings.Join([]string{kv["platform"], kv["label"], kv["application_guid"]}, "|")
				//key := strings.Join([]string{kv["platform"], kv["name"], "07f8c5951cef9eb4121771a9a96f73b4"}, "|")
				//c.Logger.Debugf("container info %v", key)
				infosi, ok := c.InfoFlusher.Info.LoadOrStore(key, make(map[string]map[string]string))
				infos := infosi.(map[string]map[string]string)
				infos[kv["container"]] = map[string]string{
					"pod":        kv["pod"],
					"id":         kv["container_id"],
					"image":      kv["image"],
					"guid":       kv["application_guid"],
					"name":       kv["container"],
					"agent_guid": kv["agent_guid"],
					"platform":   kv["platform"],
				}
				if !ok {
					c.InfoFlusher.Func.Store(key, func(k, v interface{}) error {
						guid := strings.Split(k.(string), "|")[2]
						bts, _ := json.Marshal(v)
						if err := c.DataBase.InstanceRuntimeContainerInfoUpdate(guid, string(bts)); err != nil {
							var data *meta.Instance
							if err = c.DataBase.InstanceGet(guid, &data); !errors.Is(err, gerrors.DataNotFind) {
								c.Logger.Errorf("update container_info %v", err)
							}
						}
						return nil
					})
				}
			}
		}
	case "gluenets":
		// don't support now
		//key = strings.Join([]string{kv["name"], kv["guid"]}, "|")
	}
}
